﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using DataModel;

namespace BasicDataManagement
{
    public class OpFromXML
    {
        private OpFromXML() { }
        private static OpFromXML instance;
        private static string dataDirectory;

        private static OpFromXML Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new OpFromXML();
                    return instance;
                }
                return instance;
            }
        }


        public static OpFromXML GetInstance()
        {
            return GetInstance(System.IO.Directory.GetCurrentDirectory());
        }

        public static OpFromXML GetInstance(string dirPath)
        {
            dataDirectory = dirPath + @"\TestData\";
            return Instance;
        }

        #region 读取分类

        public List<string> LoadMaterialCategory()
        {
            return LoadCategory("Material.xml", "MaterialCategory");
        }

        public List<string> LoadOptionCategory()
        {
            return LoadCategory("Option.xml", "OptionCategory");
        }

        public List<string> LoadComboCategory()
        {
            return LoadCategory("Combo.xml", "ComboCategory");
        }

        public List<string> LoadFixedDishCategory()
        {
            return LoadCategory("FixedDish.xml", "FixedDishCategory");
        }

        public List<string> LoadReplaceableDishCategory()
        {
            return LoadCategory("ReplaceableDish.xml", "ReplaceableDishCategory");
        }

        #endregion

        private List<string> LoadCategory(string filename, string catname)
        {
            XElement cat = XElement.Load(dataDirectory + filename);
            var cats = cat.Elements();
            List<string> catNames = new List<string>();
            foreach (var t in cats)
            {
                catNames.Add(t.Attribute("name").Value);
            }
            return catNames;
        }

        #region 读取单项条目名


        public List<string> LoadMateriaclItemName(string categoryName)
        {
            return LoadItem("Material.xml", categoryName);
        }

        public List<string> LoadOptionItemName(string categoryName)
        {
            return LoadItem("Option.xml", categoryName);
        }

        public List<string> LoadComboItemName(string categoryName)
        {
            return LoadItem("Combo.xml", categoryName);
        }

        public List<string> LoadFixedDishItemName(string categoryName)
        {
            return LoadItem("FixedDish.xml", categoryName);
        }

        public List<string> LoadReplaceableDishItemName(string categoryName)
        {
            return LoadItem("ReplaceableDish.xml", categoryName);
        }

        public List<string> LoadMateriaclItemName()
        {
            return LoadItem("Material.xml");
        }

        public List<string> LoadOptionItemName()
        {
            return LoadItem("Option.xml");
        }

        public List<string> LoadComboItemName()
        {
            return LoadItem("Combo.xml");
        }

        public List<string> LoadFixedDishItemName()
        {
            return LoadItem("FixedDish.xml");
        }

        public List<string> LoadReplaceableDishItemName()
        {
            return LoadItem("ReplaceableDish.xml");
        }

        #endregion

        private List<string> LoadItem(string filename, string catname)
        {
            XElement cat = XElement.Load(dataDirectory + filename);
            var items = from d in
                            (from c in cat.Elements()
                             where c.Attribute("name").Value == catname
                             select c).Elements()
                        select d.Attribute("name").Value;

            return items.ToList();
        }

        private List<string> LoadItem(string filename)
        {
            XElement cat = XElement.Load(dataDirectory + filename);
            var items = from c in cat.Elements().Elements()
                        select c.Attribute("name").Value;
            return items.ToList();
        }

        //获取单项对象
        public List<MaterialObject> LoadMaterialObjects()
        {
            XElement cat = XElement.Load(dataDirectory + "Material.xml");
            List<MaterialObject> objList = new List<MaterialObject>();

            var catList = from c in cat.Elements()
                          select c;
            foreach (var t in catList)
            {
                var materialList = from c in t.Elements()
                                   select new MaterialObject(c.Attribute("name").Value, t.Attribute("name").Value);
                foreach (var p in materialList)
                {
                    objList.Add(p);
                }
            }
            return objList;
        }
        public List<MaterialObject> LoadMaterialObjects(string categoryName)
        {
            XElement cat = XElement.Load(dataDirectory + "Material.xml");
            List<MaterialObject> objList = new List<MaterialObject>();

            var materialList = (from c in cat.Elements()
                                where c.Attribute("name").Value == categoryName
                                select c).Elements();
            foreach (var t in materialList)
            {
                objList.Add(new MaterialObject(t.Attribute("name").Value, categoryName));
            }

            return objList;
        }

        public List<FixedDishObject> LoadFixedDishObjects()
        {
            XElement cat = XElement.Load(dataDirectory + "FixedDish.xml");
            List<FixedDishObject> objList = new List<FixedDishObject>();

            //获取分类列表
            var fdCarList = from c in cat.Elements()
                            select c;

            foreach (var t in fdCarList)
            {
                //获取分类下的单项
                var fdobj = from c in t.Elements()
                            select c;

                foreach (var d in fdobj)
                {
                    //获取单项的成分
                    var ingreList = from e in d.Elements()
                                    select new Ingredient(e.Attribute("name").Value, e.Attribute("unit").Value, Convert.ToDouble(e.Attribute("dosage").Value));

                    FixedDishObject fdo = new FixedDishObject(d.Attribute("name").Value, t.Attribute("name").Value);
                    fdo.IngredientList = new List<Ingredient>(ingreList);
                    objList.Add(fdo);
                }
            }
            return objList;
        }

        public List<FixedDishObject> LoadFixedDishObjects(string catName)
        {
            XElement cat = XElement.Load(dataDirectory + "FixedDish.xml");
            List<FixedDishObject> objList = new List<FixedDishObject>();
            var fdCatList = from c in cat.Elements()
                            where c.Attribute("name").Value == catName
                            select c;

            foreach (var t in fdCatList)
            {
                //获取分类下的单项
                var fdobj = from c in t.Elements()
                            select c;

                foreach (var d in fdobj)
                {
                    //获取单项的成分
                    var ingreList = from e in d.Elements()
                                    select new Ingredient(e.Attribute("name").Value, e.Attribute("unit").Value, Convert.ToDouble(e.Attribute("dosage").Value));

                    FixedDishObject fdo = new FixedDishObject(d.Attribute("name").Value, t.Attribute("name").Value);
                    fdo.IngredientList = new List<Ingredient>(ingreList);
                    objList.Add(fdo);
                }
            }
            return objList;
        }

        public List<ComboObject> LoadComboObjects()
        {
            XElement cat = XElement.Load(dataDirectory + "Combo.xml");
            List<ComboObject> objList = new List<ComboObject>();

            //获取套餐分类列表
            var comboCatList = from c in cat.Elements()
                               select c;
            foreach (var comboCat in comboCatList)
            {
                //获取分类下套餐列表
                var comboList = from c in comboCat.Elements()
                                select c;
                foreach (var combo in comboList)
                {
                    //获取套餐下组分列表
                    var componentList = from c in combo.Elements()
                                        select c;
                    List<ComboComponentObject> componentObjList = new List<ComboComponentObject>();
                    foreach (var component in componentList)
                    {
                        //获取组分下单品列表
                        var fixedDishList = from c in component.Elements()
                                            select new Ingredient(c.Attribute("name").Value, c.Attribute("unit").Value, Convert.ToDouble(c.Attribute("dosage").Value));
                        ComboComponentObject componentObj = new ComboComponentObject(component.Attribute("name").Value);
                        componentObj.IngredientList = fixedDishList.ToList();
                        componentObjList.Add(componentObj);
                    }
                    ComboObject comboObj = new ComboObject(combo.Attribute("name").Value, comboCat.Attribute("name").Value);
                    comboObj.ComponentList = componentObjList;
                    objList.Add(comboObj);
                }
            }
            return objList;
        }

        public List<ComboObject> LoadComboObjects(string catName)
        {
            XElement cat = XElement.Load(dataDirectory + "Combo.xml");
            List<ComboObject> objList = new List<ComboObject>();

            //获取套餐分类列表
            var comboCatList = from c in cat.Elements()
                               where c.Attribute("name").Value == catName
                               select c;
            foreach (var comboCat in comboCatList)
            {
                //获取分类下套餐列表
                var comboList = from c in comboCat.Elements()
                                select c;
                foreach (var combo in comboList)
                {
                    //获取套餐下组分列表
                    var componentList = from c in combo.Elements()
                                        select c;
                    List<ComboComponentObject> componentObjList = new List<ComboComponentObject>();
                    foreach (var component in componentList)
                    {
                        //获取组分下单品列表
                        var fixedDishList = from c in component.Elements()
                                            select new Ingredient(c.Attribute("name").Value, c.Attribute("unit").Value, Convert.ToDouble(c.Attribute("dosage").Value));
                        ComboComponentObject componentObj = new ComboComponentObject(component.Attribute("name").Value);
                        componentObj.IngredientList = fixedDishList.ToList();
                        componentObjList.Add(componentObj);
                    }
                    ComboObject comboObj = new ComboObject(combo.Attribute("name").Value, comboCat.Attribute("name").Value);
                    comboObj.ComponentList = componentObjList;
                    objList.Add(comboObj);
                }
            }
            return objList;
        }

        public List<OptionObject> LoadOptionObjects()
        {
            XElement cat = XElement.Load(dataDirectory + "Option.xml");
            List<OptionObject> objList = new List<OptionObject>();

            var optCatList = from c in cat.Elements()
                             select c;
            foreach (var optCat in optCatList)
            {
                var optList = from c in optCat.Elements()
                              select c;
                foreach (var opt in optList)
                {
                    var ingreList = from ingre in opt.Elements()
                                    select new Ingredient(ingre.Attribute("name").Value, ingre.Attribute("unit").Value, Convert.ToDouble(ingre.Attribute("dosage").Value));
                    OptionObject optObj = new OptionObject(opt.Attribute("name").Value, optCat.Attribute("name").Value);
                    optObj.IngredientList = ingreList.ToList();
                    objList.Add(optObj);
                }
            }

            return objList;
        }

        public List<OptionObject> LoadOptionObjects(string catName)
        {
            XElement cat = XElement.Load(dataDirectory + "Option.xml");
            List<OptionObject> objList = new List<OptionObject>();

            var optCatList = from c in cat.Elements()
                             where c.Attribute("name").Value == catName
                             select c;
            foreach (var optCat in optCatList)
            {
                var optList = from c in optCat.Elements()
                              select c;
                foreach (var opt in optList)
                {
                    var ingreList = from ingre in opt.Elements()
                                    select new Ingredient(ingre.Attribute("name").Value, ingre.Attribute("unit").Value, Convert.ToDouble(ingre.Attribute("dosage").Value));
                    OptionObject optObj = new OptionObject(opt.Attribute("name").Value, optCat.Attribute("name").Value);
                    optObj.IngredientList = ingreList.ToList();
                    objList.Add(optObj);
                }
            }

            return objList;
        }

        public List<ReplaceableDishObject> LoadReplaceableDishObjects()
        {
            XElement cat = XElement.Load(dataDirectory + @"ReplaceableDish.xml");
            List<ReplaceableDishObject> objList = new List<ReplaceableDishObject>();

            var rDishCatList = from c in cat.Elements()
                               select c;
            foreach (var rDishCat in rDishCatList)
            {
                var rDishList = from c in rDishCat.Elements()
                                select c;
                foreach (var rDish in rDishList)
                {
                    var materialList = from material in rDish.Element("MaterialList").Elements()
                                       select new Ingredient(material.Attribute("name").Value, material.Attribute("unit").Value, Convert.ToDouble(material.Attribute("dosage").Value));
                    var optionList = from option in rDish.Element("OptionList").Elements()
                                     select new Ingredient(option.Attribute("name").Value, option.Attribute("unit").Value, Convert.ToDouble(option.Attribute("dosage").Value));

                    ReplaceableDishObject rDishObj = new ReplaceableDishObject(rDish.Attribute("name").Value, rDishCat.Attribute("name").Value);
                    rDishObj.MaterialList = materialList.ToList();
                    rDishObj.OptionList = optionList.ToList();
                    objList.Add(rDishObj);
                }
            }
            return objList;
        }

        public List<ReplaceableDishObject> LoadReplaceableDishObjects(string catName)
        {
            XElement cat = XElement.Load(dataDirectory + @"ReplaceableDish.xml");
            List<ReplaceableDishObject> objList = new List<ReplaceableDishObject>();

            var rDishCatList = from c in cat.Elements()
                               where c.Attribute("name").Value == catName
                               select c;
            foreach (var rDishCat in rDishCatList)
            {
                var rDishList = from c in rDishCat.Elements()
                                select c;
                foreach (var rDish in rDishList)
                {
                    var materialList = from material in rDish.Element("MaterialList").Elements()
                                       select new Ingredient(material.Attribute("name").Value, material.Attribute("unit").Value, Convert.ToDouble(material.Attribute("dosage").Value));
                    var optionList = from option in rDish.Element("OptionList").Elements()
                                     select new Ingredient(option.Attribute("name").Value, option.Attribute("unit").Value, Convert.ToDouble(option.Attribute("dosage").Value));

                    ReplaceableDishObject rDishObj = new ReplaceableDishObject(rDish.Attribute("name").Value, rDishCat.Attribute("name").Value);
                    rDishObj.MaterialList = materialList.ToList();
                    rDishObj.OptionList = optionList.ToList();
                    objList.Add(rDishObj);
                }
            }
            return objList;
        }

        public List<string> LoadReplaceableDishItemOptionNames(string rDishName)
        {
            XElement cat = XElement.Load(dataDirectory + @"ReplaceableDish.xml");
            //cat.Elements().Elements().Elements("OptionList").Elements("Option").Attributes("name")
            var optionNames = from d in
                                 ((from c in cat.Elements().Elements()
                                   where c.Attribute("name").Value == rDishName
                                   select c.Elements("OptionList").Elements("Option").Attributes("name")).First())
                             select d.Value;
            //return new List<string>();
            return optionNames.ToList();

            throw new NotImplementedException();
        }

        public List<string> LoadComboItemComponentNames(string comboName)
        {
            XElement cat = XElement.Load(dataDirectory + @"Combo.xml");
            var componentNames = from d in
                                     ((from c in cat.Elements().Elements()
                                       where c.Attribute("name").Value == comboName
                                       select c.Elements().Attributes("name")).First())
                                 select d.Value;

            return componentNames.ToList();
        }

        public List<string> LoadComboItemComponentIngredientNames(string comboName, string componentName)
        {
            var cat3 = XElement.Load(dataDirectory + @"Combo.xml");
            var elementNames = from e in
                              (from d in
                                   (from c in cat3.Elements().Elements()
                                    where c.Attribute("name").Value == comboName
                                    select c).Elements()
                               where d.Attribute("name").Value == componentName
                               select d).Elements().Attributes("name")
                          select e.Value;

            return elementNames.ToList();
        }

        #region LoadXxxSimpleObjects 系列方法

        public List<IngredientSimpleObject> LoadMaterialSimpleObjects()
        {
            return LoadSimpleObjects("Material.xml");
        }

        public List<IngredientSimpleObject> LoadOptionSimpleObjects()
        {
            return LoadSimpleObjects("Option.xml");
        }

        public List<IngredientSimpleObject> LoadFixedDishSimpleObjects()
        {
            return LoadSimpleObjects("FixedDish.xml");
        }

        public List<IngredientSimpleObject> LoadReplaceableDishSimpleObjects()
        {
            return LoadSimpleObjects("ReplaceableDish.xml");
        }

        public List<IngredientSimpleObject> LoadComboSimpleObjects()
        {
            return LoadSimpleObjects("Combo.xml");
        }

        private List<IngredientSimpleObject> LoadSimpleObjects(string fileName)
        {
            var file = XElement.Load(dataDirectory + fileName);
            var resultList = from a in file.Elements().Elements()
                             select new IngredientSimpleObject(a.Attribute("name").Value, a.Attribute("unit").Value);
            return resultList.ToList();
        }

        #endregion

        #region IOpertation 成员


        public void AddBill(List<BillItem> billItemList)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public void UpdateMaterial(MaterialObject materialObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateOption(OptionObject optionObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateFixedDish(FixedDishObject fdObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateCombo(ComboObject comboObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateReplaceableDish(ReplaceableDishObject rdObj)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员

        public void CreateCategory(ObjectType type, string catName)
        {
            throw new NotImplementedException();
        }

        public void CreateObject(ObjectType type, object newObj)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public List<StockRecordItem> LoadMaterialStockRecordsAll()
        {
            throw new NotImplementedException();
        }

        public List<StockRecordItem> LoadMaterialStockRecordsCategory(string categoryName)
        {
            throw new NotImplementedException();
        }

        public List<StockRecordItem> LoadMaterialStockRecordsMaterial(string MaterialName)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public void UpdateMaterial(string PreviousName, MaterialObject materialObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateOption(string PreviousName, OptionObject optionObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateFixedDish(string PreviousName, FixedDishObject fdObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateCombo(string PreviousName, ComboObject comboObj)
        {
            throw new NotImplementedException();
        }

        public void UpdateReplaceableDish(string PreviousName, ReplaceableDishObject rdObj)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public List<AuthorityGroup> LoadAuthorityGroups()
        {
            throw new NotImplementedException();
        }

        public AuthorityGroup LoadAuthorityGroup(string groupName)
        {
            throw new NotImplementedException();
        }

        public List<StaffInfo> LoadStaffs()
        {
            throw new NotImplementedException();
        }

        public List<StaffInfo> LoadStaffs(string groupName)
        {
            throw new NotImplementedException();
        }

        public void AddAuthorityGroup(AuthorityGroup newGroup)
        {
            throw new NotImplementedException();
        }

        public void AddStaff(StaffInfo staff)
        {
            throw new NotImplementedException();
        }

        public void UpdateStaff(StaffInfo staff)
        {
            throw new NotImplementedException();
        }

        public void UpdateAuthorityGroup(AuthorityGroup group)
        {
            throw new NotImplementedException();
        }

        public void DeleteAuthorityGroup(AuthorityGroup group)
        {
            throw new NotImplementedException();
        }

        public void DeleteStaff(StaffInfo staff)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public AuthorityGroup Login(string lognum, string pwd)
        {
            throw new NotImplementedException();
        }

        #endregion





        #region IOpertation 成员


        public void AddMaterialStockRecord(StockRecordItem record)
        {
            throw new NotImplementedException();
        }

        #endregion



        #region IOpertation 成员


        public void Logout(SystemUser user)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public int AddBill(List<BillItem> billItemList, int logid)
        {
            throw new NotImplementedException();
        }

        #endregion


        #region IOpertation 成员


        public int AddKitchenDisplay(int billid, string display, string waitingCard)
        {
            throw new NotImplementedException();
        }

        public string LoadKitchenDisplay()
        {
            throw new NotImplementedException();
        }

        public void DeleteKitchenDisplay(int billid)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public int AddKitchenBill(int billid, string dishes, string waitingCard)
        {
            throw new NotImplementedException();
        }

        public int AddKitchenBillItem(int billid, string dishName)
        {
            throw new NotImplementedException();
        }

        public void DeleteKitchenBill(int id)
        {
            throw new NotImplementedException();
        }

        public void DeleteKitchenBillItem(int itemID)
        {
            throw new NotImplementedException();
        }

        public List<string> LoadKitchenBill()
        {
            throw new NotImplementedException();
        }

        public List<string> LoadKitchenBillItem()
        {
            throw new NotImplementedException();
        }

        #endregion


        #region IOpertation 成员


        public int AddBill(List<BillItem> billItemList, int logid, decimal discount)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public void AddMoneyRecord(int logID, string takerJobNum, bool isTake, decimal value)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员


        public int AddBill(List<BillItem> billItemList, int logid, decimal discount, string eatPlace)
        {
            throw new NotImplementedException();
        }

        public int AddKitchenBill(int billid, string dishes, string waitingCard, string eatPlace)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOpertation 成员



        #endregion
    }
}
